﻿//
// WorkflowSharp.Dom.SequenceNode.cs
//
// Authors:
// 	Perciun Andrei (perciun.andrei@gmail.com)
//
// Copyright (C) 2008 Perciun Andrei (perciun.andrei@gmail.com)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;

namespace WorkflowSharp.Dom
{
    using Interfaces;

    public class SequenceNode<Parent> : WorkflowNode<Parent>, IExecutable<SequenceNode<Parent>>, IConditionable<SequenceNode<Parent>>, IParallelable<SequenceNode<Parent>>,
        IEmitable<SequenceNode<Parent>>, IWaitable<SequenceNode<Parent>>
    {
        private readonly List<WorkflowNode<SequenceNode<Parent>>> nodes = new List<WorkflowNode<SequenceNode<Parent>>>();

        internal SequenceNode(Parent parent, string id)
            : base(parent, id)
        {
        }

        public ConditionNode<Condition, Result, SequenceNode<Parent>> condition<Condition, Result>()
            where Condition : ICondition<Result>
            where Result : IEquatable<Result>
        {
            return condition<Condition, Result>(NewId());
        }

        public ConditionNode<Condition, Result, SequenceNode<Parent>> condition<Condition, Result>(string nodeId)
            where Condition : ICondition<Result>
            where Result : IEquatable<Result>
        {
            ConditionNode<Condition, Result, SequenceNode<Parent>> node = new ConditionNode<Condition, Result, SequenceNode<Parent>>(this, nodeId);
            nodes.Add(node);
            return node;
        }

        public ExecuteNode<Action, SequenceNode<Parent>> execute<Action>()
            where Action : IAction
        {
            return execute<Action>(NewId());
        }

        public ExecuteNode<Action, SequenceNode<Parent>> execute<Action>(string nodeId)
            where Action : IAction
        {
            ExecuteNode<Action, SequenceNode<Parent>> node = new ExecuteNode<Action, SequenceNode<Parent>>(this, nodeId);
            nodes.Add(node);
            return node;
        }

        public ParallelNode<SequenceNode<Parent>> parallel()
        {
            return parallel(NewId());
        }

        public ParallelNode<SequenceNode<Parent>> parallel(string nodeId)
        {
            ParallelNode<SequenceNode<Parent>> node = new ParallelNode<SequenceNode<Parent>>(this, nodeId);
            nodes.Add(node);
            return node;
        }

        public EmitNode<Signal, SequenceNode<Parent>> emit<Signal>()
            where Signal : ISignal
        {
            throw new NotImplementedException();
        }

        public EmitNode<Signal, SequenceNode<Parent>> emit<Signal>(string nodeId)
            where Signal : ISignal
        {
            EmitNode<Signal, SequenceNode<Parent>> node = new EmitNode<Signal, SequenceNode<Parent>>(this, nodeId);
            nodes.Add(node);
            return node;
        }

        public WaitNode<Signal, SequenceNode<Parent>> wait<Signal>()
           where Signal : ISignal
        {
            return wait<Signal>(NewId());
        }

        public WaitNode<Signal, SequenceNode<Parent>> wait<Signal>(string nodeId)
            where Signal : ISignal
        {
            WaitNode<Signal, SequenceNode<Parent>> node = new WaitNode<Signal, SequenceNode<Parent>>(this, nodeId);
            nodes.Add(node);
            return node;
        }
    }
}
